<!DOCTYPE html>
<html>
<head>
    <title>Rotating Liquid Surface Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="500" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Style settings
        ctx.lineWidth = 2;
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.font = 'bold 18px sans-serif';

        // Origin coordinates
        const ox = 250;
        const oy = 350;

        // Helper function to draw an arrow
        function drawArrow(fromX, fromY, toX, toY) {
            const headLength = 8;
            const dx = toX - fromX;
            const dy = toY - fromY;
            const angle = Math.atan2(dy, dx);

            ctx.beginPath();
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle - Math.PI / 6), toY - headLength * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle + Math.PI / 6), toY - headLength * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // 1. Draw Axes
        // z-axis
        drawArrow(ox, oy, ox, 50);
        ctx.fillText('z', ox - 20, 60);
        // r-axis
        drawArrow(ox - 220, oy, ox + 220, oy);
        ctx.fillText('r', ox + 225, oy + 8);
        // Origin label
        ctx.fillText('0', ox - 20, oy + 20);

        // 2. Draw the parabolic surface
        const k = 0.0055; // Curvature of the parabola
        ctx.beginPath();
        const r_max = 180;
        const z_max = k * r_max * r_max;
        ctx.moveTo(ox - r_max, oy - z_max);
        // Use a quadratic curve for the parabola shape
        ctx.quadraticCurveTo(ox, oy + 10, ox + r_max, oy - z_max);
        ctx.stroke();

        // 3. Draw rotation symbol
        ctx.beginPath();
        ctx.arc(ox, 100, 40, Math.PI * 1.3, Math.PI * 1.7);
        ctx.stroke();
        // Arrowheads for rotation symbol
        drawArrow(ox + 40 * Math.cos(Math.PI * 1.7), 100 + 40 * Math.sin(Math.PI * 1.7), ox + 38 * Math.cos(Math.PI * 1.75) + 5, 100 + 38 * Math.sin(Math.PI * 1.75), 5);
        drawArrow(ox + 40 * Math.cos(Math.PI * 1.3), 100 + 40 * Math.sin(Math.PI * 1.3), ox + 38 * Math.cos(Math.PI * 1.25) - 5, 100 + 38 * Math.sin(Math.PI * 1.25), 5);
        ctx.font = 'italic bold 22px serif';
        ctx.fillText('ω', ox - 65, 105);
        ctx.font = 'bold 18px sans-serif';


        // 4. Draw the force diagram at a point on the curve
        const r_p = 100;
        const z_p = k * r_p * r_p;
        const px = ox + r_p; // Particle x
        const py = oy - z_p; // Particle y

        // Draw helper lines (tangent and normal) at the particle position
        ctx.save();
        ctx.translate(px, py);
        const tangent_angle = Math.atan(2 * k * r_p);
        ctx.rotate(-tangent_angle);
        ctx.beginPath();
        ctx.moveTo(-40, 0);
        ctx.lineTo(40, 0);
        ctx.moveTo(0, -40);
        ctx.lineTo(0, 40);
        ctx.stroke();
        ctx.restore();

        // Define force vector lengths
        const gravity_len = 60;
        const centripetal_len = 60; 

        // Draw Gravity vector
        drawArrow(px, py, px, py + gravity_len);
        ctx.fillText('gravity', px - 10, py + gravity_len + 20);

        // Draw Centripetal Force vector
        drawArrow(px, py, px - centripetal_len, py);
        ctx.fillText('centri-', px - centripetal_len - 55, py - 5);
        ctx.fillText('petal', px - centripetal_len - 50, py + 15);
        ctx.fillText('force', px - centripetal_len - 50, py + 35);


        // Draw Supporting Force vector
        const support_angle = Math.atan2(-gravity_len, -centripetal_len);
        const support_len = Math.sqrt(gravity_len * gravity_len + centripetal_len * centripetal_len);
        drawArrow(px, py, px + support_len * Math.cos(support_angle), py + support_len * Math.sin(support_angle));
        ctx.fillText('supporting', px + support_len * Math.cos(support_angle) - 20, py + support_len * Math.sin(support_angle) - 25);
        ctx.fillText('force', px + support_len * Math.cos(support_angle) - 5, py + support_len * Math.sin(support_angle) - 5);


        // Draw angle θ
        const angle_radius = 25;
        const start_angle = -Math.PI / 2; // Vertical up
        const end_angle = support_angle;
        ctx.beginPath();
        ctx.arc(px, py, angle_radius, start_angle, end_angle, true);
        ctx.stroke();
        ctx.font = 'italic 18px serif';
        ctx.fillText('θ', px - angle_radius * 0.7, py - angle_radius * 0.7);
        ctx.font = 'bold 18px sans-serif';

        // 5. Draw Figure Caption
        ctx.fillText('Fig. 1.23', ox - 40, oy + 80);

    </script>
</body>
</html>